// Error Handling and Logging System - 错误处理和日志系统

export enum ErrorCode {
    // 工具相关错误
    TOOL_NOT_FOUND = 'TOOL_NOT_FOUND',
    TOOL_EXECUTION_FAILED = 'TOOL_EXECUTION_FAILED',
    TOOL_VALIDATION_FAILED = 'TOOL_VALIDATION_FAILED',
    TOOL_TIMEOUT = 'TOOL_TIMEOUT',
    TOOL_PERMISSION_DENIED = 'TOOL_PERMISSION_DENIED',

    // 系统相关错误
    INITIALIZATION_FAILED = 'INITIALIZATION_FAILED',
    CONFIGURATION_ERROR = 'CONFIGURATION_ERROR',
    RESOURCE_NOT_AVAILABLE = 'RESOURCE_NOT_AVAILABLE',
    NETWORK_ERROR = 'NETWORK_ERROR',

    // 文件操作错误
    FILE_NOT_FOUND = 'FILE_NOT_FOUND',
    FILE_ACCESS_DENIED = 'FILE_ACCESS_DENIED',
    FILE_OPERATION_FAILED = 'FILE_OPERATION_FAILED',

    // 进程管理错误
    PROCESS_START_FAILED = 'PROCESS_START_FAILED',
    PROCESS_NOT_FOUND = 'PROCESS_NOT_FOUND',
    PROCESS_OPERATION_FAILED = 'PROCESS_OPERATION_FAILED',

    // 记忆管理错误
    MEMORY_STORAGE_FAILED = 'MEMORY_STORAGE_FAILED',
    MEMORY_RETRIEVAL_FAILED = 'MEMORY_RETRIEVAL_FAILED',
    MEMORY_ACCESS_DENIED = 'MEMORY_ACCESS_DENIED',

    // API 相关错误
    API_KEY_INVALID = 'API_KEY_INVALID',
    API_RATE_LIMIT = 'API_RATE_LIMIT',
    API_REQUEST_FAILED = 'API_REQUEST_FAILED',

    // 通用错误
    UNKNOWN_ERROR = 'UNKNOWN_ERROR',
    INVALID_PARAMETER = 'INVALID_PARAMETER',
    OPERATION_CANCELLED = 'OPERATION_CANCELLED'
}

export interface ErrorDetails {
    code: ErrorCode;
    message: string;
    details?: any;
    timestamp: Date;
    context: Record<string, any> | undefined;
    stack: string | undefined;
}

/**
 * 自定义错误类
 */
export class AugmentError extends Error {
    public readonly code: ErrorCode;
    public readonly details?: any;
    public readonly timestamp: Date;
    public readonly context?: Record<string, any> | undefined;

    constructor(code: ErrorCode, message: string, details?: any, context?: Record<string, any>) {
        super(message);
        this.name = 'AugmentError';
        this.code = code;
        this.details = details;
        this.timestamp = new Date();
        this.context = context;

        // 保持堆栈跟踪
        if (Error.captureStackTrace) {
            Error.captureStackTrace(this, AugmentError);
        }
    }

    toJSON(): ErrorDetails {
        return {
            code: this.code,
            message: this.message,
            details: this.details,
            timestamp: this.timestamp,
            context: this.context,
            stack: this.stack
        };
    }

    static fromError(error: Error, code: ErrorCode = ErrorCode.UNKNOWN_ERROR, context?: Record<string, any>): AugmentError {
        if (error instanceof AugmentError) {
            return error;
        }

        return new AugmentError(code, error.message, { originalError: error }, context);
    }
}

/**
 * 错误处理器
 */
export class ErrorHandler {
    private logger: Logger;
    private errorCallbacks: Map<ErrorCode, Array<(error: AugmentError) => void>> = new Map();

    constructor(logger: Logger) {
        this.logger = logger;
    }

    /**
     * 处理错误
     */
    handleError(error: Error | AugmentError, context?: Record<string, any>): AugmentError {
        const augmentError = error instanceof AugmentError 
            ? error 
            : AugmentError.fromError(error, ErrorCode.UNKNOWN_ERROR, context);

        // 记录错误
        this.logger.error('Error occurred:', augmentError.toJSON());

        // 调用错误回调
        const callbacks = this.errorCallbacks.get(augmentError.code) || [];
        callbacks.forEach(callback => {
            try {
                callback(augmentError);
            } catch (callbackError) {
                this.logger.error('Error in error callback:', undefined, callbackError instanceof Error ? callbackError : new Error(String(callbackError)));
            }
        });

        return augmentError;
    }

    /**
     * 注册错误回调
     */
    onError(code: ErrorCode, callback: (error: AugmentError) => void): void {
        if (!this.errorCallbacks.has(code)) {
            this.errorCallbacks.set(code, []);
        }
        this.errorCallbacks.get(code)!.push(callback);
    }

    /**
     * 移除错误回调
     */
    removeErrorCallback(code: ErrorCode, callback: (error: AugmentError) => void): void {
        const callbacks = this.errorCallbacks.get(code);
        if (callbacks) {
            const index = callbacks.indexOf(callback);
            if (index > -1) {
                callbacks.splice(index, 1);
            }
        }
    }

    /**
     * 创建工具相关错误
     */
    createToolError(toolName: string, message: string, details?: any): AugmentError {
        return new AugmentError(
            ErrorCode.TOOL_EXECUTION_FAILED,
            `Tool ${toolName}: ${message}`,
            details,
            { toolName }
        );
    }

    /**
     * 创建文件操作错误
     */
    createFileError(operation: string, filePath: string, message: string): AugmentError {
        return new AugmentError(
            ErrorCode.FILE_OPERATION_FAILED,
            `File ${operation} failed for ${filePath}: ${message}`,
            { operation, filePath }
        );
    }

    /**
     * 创建进程错误
     */
    createProcessError(operation: string, processId: string | number, message: string): AugmentError {
        return new AugmentError(
            ErrorCode.PROCESS_OPERATION_FAILED,
            `Process ${operation} failed for ${processId}: ${message}`,
            { operation, processId }
        );
    }
}

export enum LogLevel {
    DEBUG = 0,
    INFO = 1,
    WARN = 2,
    ERROR = 3
}

export interface LogEntry {
    level: LogLevel;
    message: string;
    timestamp: Date;
    context?: Record<string, any>;
    error?: Error;
}

/**
 * 日志记录器
 */
export class Logger {
    private logLevel: LogLevel = LogLevel.INFO;
    private logEntries: LogEntry[] = [];
    private maxLogEntries: number = 1000;
    private logCallbacks: Array<(entry: LogEntry) => void> = [];

    constructor(logLevel: LogLevel = LogLevel.INFO) {
        this.logLevel = logLevel;
    }

    /**
     * 设置日志级别
     */
    setLogLevel(level: LogLevel): void {
        this.logLevel = level;
    }

    /**
     * 添加日志回调
     */
    addLogCallback(callback: (entry: LogEntry) => void): void {
        this.logCallbacks.push(callback);
    }

    /**
     * 移除日志回调
     */
    removeLogCallback(callback: (entry: LogEntry) => void): void {
        const index = this.logCallbacks.indexOf(callback);
        if (index > -1) {
            this.logCallbacks.splice(index, 1);
        }
    }

    /**
     * 记录日志
     */
    private log(level: LogLevel, message: string, context?: Record<string, any>, error?: Error): void {
        if (level < this.logLevel) {
            return;
        }

        const entry: LogEntry = {
            level,
            message,
            timestamp: new Date(),
            ...(context && { context }),
            ...(error && { error })
        };

        // 添加到日志条目
        this.logEntries.push(entry);

        // 限制日志条目数量
        if (this.logEntries.length > this.maxLogEntries) {
            this.logEntries.shift();
        }

        // 调用日志回调
        this.logCallbacks.forEach(callback => {
            try {
                callback(entry);
            } catch (callbackError) {
                console.error('Error in log callback:', callbackError);
            }
        });

        // 输出到控制台
        this.outputToConsole(entry);
    }

    /**
     * 输出到控制台
     */
    private outputToConsole(entry: LogEntry): void {
        const timestamp = entry.timestamp.toISOString();
        const levelName = LogLevel[entry.level];
        const prefix = `[${timestamp}] [${levelName}]`;

        switch (entry.level) {
            case LogLevel.DEBUG:
                console.debug(prefix, entry.message, entry.context || '');
                break;
            case LogLevel.INFO:
                console.info(prefix, entry.message, entry.context || '');
                break;
            case LogLevel.WARN:
                console.warn(prefix, entry.message, entry.context || '');
                break;
            case LogLevel.ERROR:
                console.error(prefix, entry.message, entry.context || '', entry.error || '');
                break;
        }
    }

    /**
     * 调试日志
     */
    debug(message: string, context?: Record<string, any>): void {
        this.log(LogLevel.DEBUG, message, context);
    }

    /**
     * 信息日志
     */
    info(message: string, context?: Record<string, any>): void {
        this.log(LogLevel.INFO, message, context);
    }

    /**
     * 警告日志
     */
    warn(message: string, context?: Record<string, any>): void {
        this.log(LogLevel.WARN, message, context);
    }

    /**
     * 错误日志
     */
    error(message: string, context?: Record<string, any>, error?: Error): void {
        this.log(LogLevel.ERROR, message, context, error);
    }

    /**
     * 获取日志条目
     */
    getLogEntries(level?: LogLevel, limit?: number): LogEntry[] {
        let entries = this.logEntries;

        if (level !== undefined) {
            entries = entries.filter(entry => entry.level >= level);
        }

        if (limit !== undefined) {
            entries = entries.slice(-limit);
        }

        return entries;
    }

    /**
     * 清空日志
     */
    clearLogs(): void {
        this.logEntries = [];
    }

    /**
     * 获取日志统计
     */
    getLogStats(): Record<string, number> {
        const stats: Record<string, number> = {};
        
        for (const level of Object.values(LogLevel)) {
            if (typeof level === 'number') {
                stats[LogLevel[level]] = this.logEntries.filter(entry => entry.level === level).length;
            }
        }

        return stats;
    }
}
